﻿/**
* @description  Class to hold all the slide data for a slide show.
*/
package com.foed.applications.slideshow {

	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;

	public class SlideShowModel extends EventDispatcher {

		static private const CLASS_FILE:String = "classFile";
		static public const SLIDES:String = "slides";
		static public const PROPERTIES:String = "properties";
		static public const CLASS_MAPPINGS:String = "classMapping";

		private var _xml:XML;
		private var _file:String;

		/**
		* @description  Loads an XML file containing the model data.
		*/
		private function loadFile():void {
			var pLoader:URLLoader = new URLLoader();
			pLoader.addEventListener(Event.COMPLETE, onComplete);
			pLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
			try {
				pLoader.load(new URLRequest(_file));
			} catch (e:Error) {
				trace(e.getStackTrace());
			}
		}
		
		/**
		* @description  Event handler for the file load completion.
		*
		* @param  pEvent  Event fired by URLLoader.
		*/
		private function onComplete(pEvent:Event):void {
			var pLoader:URLLoader = (pEvent.target as URLLoader);
			pLoader.removeEventListener(Event.COMPLETE, onComplete);
			pLoader.removeEventListener(IOErrorEvent.IO_ERROR, onError);
			XML.ignoreWhitespace = true;
			_xml = new XML(pLoader.data);
			dispatchEvent(pEvent);
		}

		/**
		* @description  Event handler for an error in the file load.
		*
		* @param  pEvent  Event fired by URLLoader.
		*/
		private function onError(pEvent:IOErrorEvent):void {
			var pLoader:URLLoader = (pEvent.target as URLLoader);
			pLoader.removeEventListener(Event.COMPLETE, onComplete);
			pLoader.removeEventListener(IOErrorEvent.IO_ERROR, onError);
			trace(pEvent.text);
		}

		/**
		* @description  Sets the XML model data for the slide show.
		*
		* @param  pXML  The XML data defining the slide show.
		*/
		public function setXML(pXML:XML):void {
			_xml = pXML;
		}
		
		/**
		* @description  Sets the path to the file to load for the XML data.
		*
		* @param  pFile  The URL to the XML file to load.
		*/
		public function setFile(pFile:String):void {
			_file = pFile;
		}
		
		/**
		* @description  Triggers the SlideShowModel instance to ready its XML,
		*				whether it was passed in directly, or if it must be loaded.
		*/
		public function fetchXML():void {
			if (_xml != null) {
				dispatchEvent(new Event(Event.COMPLETE));
			} else if (_file != null) {
				loadFile();
			} else {
				trace("no xml to load");
			}
		}
		
		/**
		* @description  Returns the XML for the specified child node name.
		*
		* @param  pChild  The name of the node to retrieve.
		*
		* @returns  The XML data stored at the specified child.
		*/
		public function getChild(pChild:String):XML {
			var pXML:XMLList = _xml.child(pChild);
			if (pXML) return pXML[0];
			return null;
		}

		/**
		* @description  Returns the XMLList instance that contains the path to the SWF file
		*				containing a slide show's external compiled classes to be loaded.
		*
		* @returns  An XMLList instance that contains the path to the compiled classes SWF to load.
		*/
		public function getClassFile():XMLList {
			return _xml.@[CLASS_FILE];
		}

	}

}